
/* Generated by Interface Builder */

#import <stdio.h>
#import <libc.h>
#import <dpsclient/wraps.h>
#import <appkit/Box.h>
#import <appkit/Button.h>
#import <appkit/ButtonCell.h>
#import <appkit/color.h>
#import <appkit/Control.h>
#import <appkit/NXBitmapImageRep.h>
#import <appkit/NXColorWell.h>
#import <appkit/OpenPanel.h>
#import <appkit/SavePanel.h>
#import <appkit/Text.h>
#import <appkit/TextField.h>
#import <appkit/View.h>
#import <appkit/Window.h>
#import "GraphicApp.h"
#import "NXBitmapImageRepControl.h"
#import "Indexer.h"
#import "Converter.h"

@implementation Indexer

	extern char		*errors[];

+ new
{
	self = [super new];
	
	[NXApp setIndexer: self];
	
	return self;
}

- setMyWText:anObject
{
	myWText = anObject;
	[myWText setIntValue: 100];
	return self;
}

- setMyXText:anObject
{
	myXText = anObject;
	[myXText setIntValue: 6];
	return self;
}

- renderImage: (id)image at: (int)x : (int)y withName: (const char *)name
{
	NXRect		miniRect;
	float			stringWidth;
	float			stringHeight;
	float			ratio;
	
	if ([image pixelsWide] > [image pixelsHigh]) {
		ratio = (float)[image pixelsHigh] / (float)[image pixelsWide];
		miniRect.origin.x = (float)x * (float)width;
		miniRect.origin.y = (float)y * ((float)height + 12.0) + 12.0;
		miniRect.size.width = (float)width;
		miniRect.size.height = (float)height * ratio;
	} else {
		ratio = (float)[image pixelsHigh] / (float)[image pixelsWide];
		miniRect.origin.x = (float)x * (float)width + ((float)width - (float)width / ratio) / 2;
		miniRect.origin.y = (float)y * ((float)height + 12.0) + 12.0;
		miniRect.size.width = (float)width / ratio;
		miniRect.size.height = (float)height;
	}
	
#ifdef DEBUG
	fprintf(stderr, "   render at (%f, %f), of size %f x %f\n",
		miniRect.origin.x, miniRect.origin.y, miniRect.size.width, miniRect.size.height);
#endif
	
	PSgsave();
		if (miniRect.size.height < height) {
			PStranslate(0, (height - miniRect.size.height) / 2);
		}
		PSgsave();
			[image drawIn: &miniRect];
		PSgrestore();
	
		PSstringwidth((char *)name, &stringWidth, &stringHeight);
		PSmoveto(x * width + width / 2 - stringWidth / 2, y * (height + 12) + 2.0);
		PSshow((char *)name);
	PSgrestore();
	
	return self;
}

- createIndex
{
	int			x;
	int			px, py;
	id			myImage;
	char			buffer[1024];
	NXRect		tRect;

	[view lockFocus];
	
	PSselectfont("Times-Roman", 12.0);
	
	NXSetColor([myColor color]);
	PSrectfill(0.0, 0.0, width * xCount, (height + 12.0) * yCount);
	NXSetColor(NX_COLORBLACK);
	
	for (x = px = 0, py = yCount - 1; x < count; x++) {
#ifdef DEBUG
		fprintf(stderr, "Working on image %s\n", files[x]);
#endif
		sprintf(buffer, "Now Loading: %s", files[x]);
		[progressTextName setStringValue: buffer];
		
		[progressTextView getBounds: &tRect];
		[progressTextView lockFocus];
			PSsetrgbcolor(0.7, 0.0, 0.0);
			PSrectfill(	tRect.origin.x + 2, tRect.origin.y + 2,
						(tRect.size.width - 4.0) * (((float)x + 0.5) /  (float)count),
						tRect.size.height - 4.0);
			PSflush();
		[progressTextView unlockFocus];
		[[progressTextView window] flushWindow];
		
		if (myImage = [images openAndReturnImage: files[x]]) {
			if ([images errorState] != CONVERT_ERR_NONE) {
				NXRunAlertPanel("Warning",
								errors[[images errorMessage]],
								"Continue", NULL, NULL);
			}
			sprintf(buffer, "Now Rendering: %s", files[x]);
			[progressTextName setStringValue: buffer];
			[progressTextView getBounds: &tRect];
			[progressTextView lockFocus];
				PSsetrgbcolor(0.7, 0.0, 0.0);
				PSrectfill(	tRect.origin.x + 2, tRect.origin.y + 2,
							(tRect.size.width - 4.0) * ((float)(x + 1) /  (float)count),
							tRect.size.height - 4.0);
				PSflush();
			[progressTextView unlockFocus];
			[[progressTextView window] flushWindow];
		
			[self renderImage: myImage at: px : py withName: files[x]];
			if (++px == xCount) {
				px = 0;
				py--;
			}
			[myImage free];
		}
		else {
			NXRunAlertPanel("Alert", 
							"Unable to open file: %s\n\n%s", 
							"Continue", NULL, NULL, 
							files[x], errors[[images errorMessage]]);
			return NO;
		}
	}

	[view unlockFocus];

	return self;
}

- createIndexView
{
	NXRect		myRect = { 0, 0, xCount * width, yCount * (height + 12.0) };

	window = [[Window alloc] 
					initContent:	&myRect
					style:		NX_PLAINSTYLE
					backing:		NX_RETAINED
					buttonMask:	0
					defer:		NO];
	view = [window contentView];

	return self;
}

- makeIndex:(id)imagesIn
{
	id 		openPanel = [OpenPanel new];
	int		x;
	NXRect	myRect;
	id		image;
	
	images = imagesIn;
	
	[[openPanel contentView] getBounds: &myRect];
	[openPanel allowMultipleFiles: YES];
	if (!saveView) {
		saveView = [saveViewWindow contentView];
		[saveView removeFromSuperview];
	}
//	[saveView sizeTo: myRect.size.width : myRect.size.height];
	[openPanel setAccessoryView: saveView];

	if (![images runOpenPanel: openPanel]) {
		[openPanel setAccessoryView: nil];
		return nil;
	}

	files = (char **)[openPanel filenames];
	chdir((char *)[openPanel directory]);

#ifdef DEBUG
	fprintf(stderr, "I should make an index for\n");
#endif
	for (x = 0; files[x]; x++) {
#ifdef DEBUG
		fprintf(stderr, "   %s\n", files[x]);
#endif
	}
	count = x;

	width = [myWText intValue];
	if (width > 400) width = 400;
	height = width;
	xCount = [myXText intValue];
	if (xCount > 20) xCount = 20;
	if (count < xCount) xCount = count;
	yCount = (count - 1) / xCount + 1;

	[progressWindow makeKeyAndOrderFront: self];
	[progressTextView getBounds: &myRect];
	[progressTextView lockFocus];
		PSsetrgbcolor(0.7, 0.0, 0.0);
		NXDrawWhiteBezel(&myRect, &myRect);
		PSflush();
	[progressTextView unlockFocus];
	[progressWindow flushWindow];

	[self createIndexView];
	[self createIndex];

	[view getBounds: &myRect];
	[view lockFocus];
	image = [[NXBitmapImageRep alloc] initData: NULL fromRect: &myRect];
	[view unlockFocus];
	
	[progressWindow close];
	[openPanel setAccessoryView: nil];
	[window free];
	
	return image; 
}

@end
